package jwlee;

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class BallFrame extends JFrame implements ActionListener, ChangeListener {
	JPanel jp_HuaBan;

	JPanel jp_YuLan;

	JSlider js_red;

	JSlider js_green;

	JSlider js_blue;

	JSlider js_size;

	int x = 45, y = 45;

	int ball_size = 30;

	Image oimage;

	Graphics og;

	public BallFrame() {
		super("ball");
	}

	public void init() {
		// 创建画板
		jp_HuaBan = new JPanel();
		jp_HuaBan.setBounds(20, 0, 450, 200);
		jp_HuaBan.setBackground(Color.white);

		// 创建球的予览框
		jp_YuLan = new JPanel();
		jp_YuLan.setBounds(350, 220, 120, 120);
		jp_YuLan.setBackground(Color.white);

		// 创建一个文本框作为状态栏
		JTextField jt_status = new JTextField("请选择球的颜色、大小然后点击按钮");
		jt_status.setBounds(1, 404, 492, 20);
		jt_status.setEditable(false);

		// 创建红、绿、蓝三个标签
		JLabel jl_red = new JLabel("红");
		jl_red.setBounds(20, 215, 30, 20);
		JLabel jl_green = new JLabel("绿");
		jl_green.setBounds(20, 260, 30, 20);
		JLabel jl_blue = new JLabel("蓝");
		jl_blue.setBounds(20, 305, 30, 20);
		// 创建红、绿、蓝三个滑块
		js_red = this.generateColorSlider();
		js_red.setBounds(50, 210, 250, 45);
		js_green = this.generateColorSlider();
		js_green.setBounds(50, 255, 250, 45);
		js_blue = this.generateColorSlider();
		js_blue.setBounds(50, 300, 250, 45);

		// 创建大小标签
		JLabel jl_size = new JLabel("大小");
		jl_size.setBounds(20, 350, 30, 20);
		// 创建球的大小的滑块
		js_size = new JSlider(SwingConstants.HORIZONTAL, 10, 50, 30);
		js_size.setBounds(50, 345, 250, 45);
		js_size.putClientProperty("JSlider.isFilled", Boolean.TRUE);
		js_size.setPaintTicks(true);
		js_size.setMajorTickSpacing(10);
		js_size.setMinorTickSpacing(5);
		js_size.setPaintLabels(true);
		js_size.addChangeListener(this);

		// 创建按钮
		JButton jb = new JButton("ball");
		jb.setBounds(350, 360, 120, 30);
		jb.addActionListener(this);

		// 将所有对象添加到窗体
		Container c = this.getContentPane();
		c.setLayout(null);
		c.add(jp_HuaBan);
		c.add(jp_YuLan);
		c.add(jl_red);
		c.add(jl_green);
		c.add(jl_blue);
		c.add(jl_size);
		c.add(js_red);
		c.add(js_green);
		c.add(js_blue);
		c.add(js_size);
		c.add(jb);
		c.add(jt_status);

		// 设置窗体的位置和大小
		this.setBounds(100, 50, 500, 450);
		this.setResizable(false);
		this.setVisible(true);
		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

		oimage = this.createImage(800, 600);
		og = oimage.getGraphics();
	}

	private JSlider generateColorSlider() {
		JSlider js = new JSlider(SwingConstants.HORIZONTAL, 0, 255, 127);
		// 填充滑块
		js.putClientProperty("JSlider.isFilled", Boolean.TRUE);
		// 绘制勾号标记
		js.setPaintTicks(true);
		// 主要的勾号标记大小
		js.setMajorTickSpacing(50);
		// 次要的勾号标记大小
		js.setMinorTickSpacing(25);
		// 显示主要刻度的数字标记
		js.setPaintLabels(true);
		// 添加监听者
		js.addChangeListener(this);

		return js;
	}

	public void actionPerformed(ActionEvent e) {
		Color ball_color = new Color(js_red.getValue(), js_green.getValue(), js_blue.getValue());
		Graphics g = jp_HuaBan.getGraphics();
		Ball l = new LBall(g, js_size.getValue(), ball_color);
		l.start();
		Ball r = new RBall(g, js_size.getValue(), ball_color);
		r.start();
	}

	public void stateChanged(ChangeEvent e) {
		// 获得jp_YuLan的画笔并在jp_YuLan的中心画个圆
		Graphics g = jp_YuLan.getGraphics();

		g.setColor(Color.white);
		g.fillOval(x, y, ball_size, ball_size);
		og.setColor(Color.white);
		og.fillOval(x, y, ball_size, ball_size);

		x = 60 - js_size.getValue() / 2;
		y = 60 - js_size.getValue() / 2;
		ball_size = js_size.getValue();

		g.setColor(new Color(js_red.getValue(), js_green.getValue(), js_blue.getValue()));
		g.fillOval(x, y, ball_size, ball_size);
		g.dispose();
		og.setColor(new Color(js_red.getValue(), js_green.getValue(), js_blue.getValue()));
		og.fillOval(x, y, ball_size, ball_size);
		og.dispose();
	}

	public void update(Graphics g) {
		Image DbBuffer = createImage(getWidth(), getHeight());
		Graphics GraImage = DbBuffer.getGraphics();
		paint(GraImage);
		GraImage.dispose();
		g.drawImage(DbBuffer, 0, 0, null);
		// if (oimage != null) {
		// og.drawImage(oimage, x, y, this);
		// }
		paint(g);
	}

	// 入口
	public static void main(String args[]) {
		new BallFrame().init();
	}

	abstract class Ball extends Thread {
		Graphics g;// 画板的句柄

		int ball_size;// 球的大小

		Color ball_color;// 球的颜色

		public Ball(Graphics j, int i, Color c) {
			g = j;
			ball_size = i;
			ball_color = c;
		}

		public void run() {
			int[] ballInfo = this.getBallInfo();
			// 位置
			int x = ballInfo[0], y = ballInfo[1];
			// 计算画球时X轴,Y轴的最大坐标
			int HuaBan_x = ballInfo[2], HuaBan_y = ballInfo[3];
			// 球移动的增量
			int x_increase = ballInfo[4], y_increase = ballInfo[5];

			while (true) {
				// 将上一次画的球擦掉
				g.setColor(Color.white);
				g.fillOval(x, y, ball_size, ball_size);
				// 在新位置画球
				g.setColor(ball_color);
				x = x + x_increase;
				y = y + y_increase;
				g.fillOval(x, y, ball_size, ball_size);

				// 判断球是否到达了边界,若到达了则转向
				if (x <= 0 || x >= HuaBan_x)
					x_increase = -x_increase;
				if (y <= 0 || y >= HuaBan_y)
					y_increase = -y_increase;
				try {
					// 休眠一段时间
					Thread.sleep(60);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		/**
		 * 
		 * @return [球位置x,球位置y,画板最大值HuaBan_x,画板最大值HuaBan_y,球移动的增量x_increase,球移动的增量y_increase]
		 */
		abstract int[] getBallInfo();

	}

	// 从窗口左面出现的球
	class LBall extends Ball {
		public LBall(Graphics j, int i, Color c) {
			super(j, i, c);
		}

		public int[] getBallInfo() {
			return new int[] { 0, 0, 450 - ball_size, 200 - ball_size, 5, 5 };
		}
	}

	// 从窗口左面出现的球
	class RBall extends Ball {
		public RBall(Graphics j, int i, Color c) {
			super(j, i, c);
		}

		public int[] getBallInfo() {
			return new int[] { 450 - ball_size, 0, 450 - ball_size, 200 - ball_size, -5, 5 };
		}
	}
}
